
<template>
  <div class="wrap">
    <div>
      <el-upload class="upload-demo"
                 ref="uploadRef"
                 :multiple="false"
                 :drag="true"
                 :auto-upload="false"
                 action=""
                 :file-list="fileList"
                 :on-change="handleChange"
                 :limit="1"
                 style="margin-bottom: 20px;">
        <div class="upload-demo-info">
          <em class="el-icon-upload upload-icon"/>
          <div class="el-upload__text">{{ $t('message.FastenerInfoImportDlg.dragHere') }}
            <em>{{ $t('message.FastenerInfoImportDlg.clickUpload') }}</em>
          </div>
        </div>
      </el-upload>
      <!--      <div v-if="errMsg !== ''" class="text-danger mt-2">{{ errMsg }}</div>-->
    </div>
    <div class="btn">
      <el-button type="primary" @click="generates">
        {{ $t('message.FastenerInfoImportDlg.Import') }}
      </el-button>
      <el-button @click="close">{{ $t('message.FastenerInfoImportDlg.close') }}</el-button>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
import { CrownCADPlugin,Point, Matrix4 } from "../../../../nodeApp/static/lib/crowncad-plugin-sdk-0.0.1";
import {PluginFunctionType} from "../../../../nodeApp/static/lib/crowncad-plugin-sdk-0.0.1";
import {request} from "../../../util/Request";
import DialogMixin from "../DialogMixin";
export default {
  mixins: [DialogMixin],
  name: "FastenerInstantiated",
  data() {
    return {
      loading: false,
      minHeight: 120,
      fileList: [], // 文件列表
      file: null,   // 当前选中的文件
      allNode: null,
      crownCADPlugin: null,
      LineNode: [],
      CircleNode: [],
      LineNodes: [],
      projectId:0,
    }
  },
  async mounted() {
    // fastenerStatisticsCommand.init(500, 300, 500, () => {
    //
    // });
    //
    this.crownCADPlugin = new CrownCADPlugin();
    //设置CrownCAD平台地址
    this.crownCADPlugin.setParentOrigin(`${window.location.protocol}//${window.location.hostname}:8080`);
    //.设置与CrownCAD平台尝试建立连接的次数
    this.crownCADPlugin.setMaxAttempt(5);
    //设置插件在CrownCAD平台显示的尺寸
    this.crownCADPlugin.setLayout(500, 500, 500);
    //.发送与CrownCAD平台建立连接的请求
    // 发送与CrownCAD平台建立连接的请求
    await this.crownCADPlugin.connect()
    await this.crownCADPlugin.request.execFunction(PluginFunctionType.LAYOUT, { minWidth: 320, width: 320, maxHeight: this.minHeight})

    // this.projectId = await fastenerStatisticsCommand.getProjectInfo();
    this.crownCADPlugin.command.clearCommand();
  },
  methods: {
    changePluginContainerHeight() {
      this.crownCADPlugin.toolQuery.changePluginContainerHeight({
        minWidth: this.$el.clientWidth,
        maxHeight: this.$el.clientHeight,
      })
    },
    //关闭
    close() {
      this.crownCADPlugin.toolQuery.closeActiveCmd();
    },
    handleChange(file) {
      this.file = file.raw; // 获取原始文件对象
      this.fileList = [file]; // 更新文件列表
      this.handleUpload(); // 自动上传文件
    },

    // 手动上传按钮点击事件
    async handleUpload() {
      if (!this.file) {
        this.$message.error('请先选择一个文件！');
        return;
      }

      try {
        // 调用 uploadFile 方法进行上传
        await this.uploadFile(this.file);
        this.$message.success('文件上传成功！');

      } catch (error) {
        this.$message.error('文件上传失败，请重试！');
      }

    },

    // async getFastenerInfo() {
    //   // 获取紧固件xml的节点信息
    //   //let GSMNode= this.allNode.Root.children[0].PartRoot.children[4].GSMNode.children;
    //   let GSMNode= this.allNode.Root.children[0].ProductRoot.children[0].ProductNode.children[0].PartNode.children[4].GSMNode.children;
    //   // LineNode储存线段信息、CircleNode储存圆弧信息
    //   this.LineNode = [];
    //   this.CircleNode = [];
    //
    //
    //   for (var i = 0; i < GSMNode.length; i++) {
    //     for (var j = 0; j < GSMNode[i].GSMNode.children.length; j++) {
    //       for (var k = 0; k < GSMNode[i].GSMNode.children[j].GSMNode.children.length; k++) {
    //         if (GSMNode[i].GSMNode.children[j].GSMNode.children[k].LineNode) {
    //           this.LineNode.push(GSMNode[i].GSMNode.children[j].GSMNode.children[k].LineNode);
    //           // this.minHeight= this.minHeight+ 100
    //         } else if (GSMNode[i].GSMNode.children[j].GSMNode.children[k].CircleNode){
    //           this.CircleNode.push(GSMNode[i].GSMNode.children[j].GSMNode.children[k].CircleNode);
    //           // this.minHeight= this.minHeight+ 50
    //         }
    //       }
    //     }
    //   }
    //
    //   await this.crownCADPlugin.request.execFunction(PluginFunctionType.LAYOUT, { minWidth: 320, width: 320, maxHeight: this.minHeight})
    // },

    async getFastenerInfo() {
      let GSMNode= []
      let ProductRoot=  this.allNode.Root.children[0].ProductRoot.children
      for (var i = 0; i < ProductRoot.length; i++) {
        if(ProductRoot[i].ProductNode) {
          let PartNode= ProductRoot[i].ProductNode.children[0].PartNode.children
          for (var j = 0; j < PartNode.length; j++){
            if (PartNode[j] && PartNode[j].GSMNode && PartNode[j].GSMNode.text && PartNode[j].GSMNode.text== "紧固件") {
              GSMNode= PartNode[j].GSMNode.children
            }
          }
        }

      }
      console.log(GSMNode)
      // LineNode储存线段信息、CircleNode储存圆弧信息
      this.LineNode= []
      this.CircleNode= []
      for (var i = 0; i < GSMNode.length; i++) {
        for (var j = 0; j < GSMNode[i].GSMNode.children.length; j++) {
          for (var k = 0; k < GSMNode[i].GSMNode.children[j].GSMNode.children.length; k++) {
            if (GSMNode[i].GSMNode.children[j].GSMNode.children[k].LineNode) {
              if(GSMNode[i].GSMNode.children[j].GSMNode.children[k].LineNode.x1=== undefined) {
                this.LineNodes.push(GSMNode[i].GSMNode.children[j].GSMNode.children[k].LineNode)
              } else {
                this.LineNode.push(GSMNode[i].GSMNode.children[j].GSMNode.children[k].LineNode)
              }

              // this.minHeight= this.minHeight+ 100
            } else if (GSMNode[i].GSMNode.children[j].GSMNode.children[k].CircleNode){
              this.CircleNode.push(GSMNode[i].GSMNode.children[j].GSMNode.children[k].CircleNode)
              // this.minHeight= this.minHeight+ 50
            }
          }
        }
      }
      console.log(this.LineNode)
      console.log(this.CircleNode)
      console.log(this.LineNodes)
    },


    //开始导入紧固件
    async generates() {
      console.log(this.LineNode);
      console.log(this.CircleNode);
      await this.crownCADPlugin.toolQuery.openLoading("正在导入，请稍候！");
      await this.crownCADPlugin.command.clearCommand();
      // 循环创建线段和圆圈
      for (var i = 0; i < this.LineNode.length; i++) {
        await this.generate(i)
      }
      // await await this.crownCADPlugin.command.execute();
      // await this.crownCADPlugin.command.clearCommand();
      for (var i = 0; i < this.CircleNode.length; i++) {
        await this.generate2(i)
      }
      // await await this.crownCADPlugin.command.execute();
      // await this.crownCADPlugin.command.clearCommand();
      for (var i = 0; i < this.LineNodes.length; i++) {
        await this.generate3(i)
      }
      await await this.crownCADPlugin.command.execute();
      await this.crownCADPlugin.command.clearCommand();
      await this.crownCADPlugin.toolQuery.closeLoading();
    },


    // 计算螺栓和螺母的矩阵信息，然后将对应的紧固件导入
    async generate(index) {
      let pointRequest = {
        "onePoint": [this.LineNode[index].x2, this.LineNode[index].y2, this.LineNode[index].z2],
        "twoPoint": [this.LineNode[index].x1, this.LineNode[index].y1, this.LineNode[index].z1],
      }

      // 计算紧固件上两点的距离
      let distance = await this.calculateDistance(pointRequest);
      let MatrixRequest
      // 组装紧固件上起点、终点、真实坐标系下起点、终点，加一个厚度字典、方向
      if(this.LineNode[index].text=== "NAS1097AD5-5" || this.LineNode[index].text=== "NAS1097AD5-6") {
        MatrixRequest= {
          "partStart": [0,  0, 0],
          "partEnd": [distance, 0, 0],
          "assemblyStart": [this.LineNode[index].x1, this.LineNode[index].y1, this.LineNode[index].z1],
          "assemblyEnd": [this.LineNode[index].x2, this.LineNode[index].y2, this.LineNode[index].z2]
        }
      } else {
        // 组装紧固件上起点、终点、真实坐标系下起点、终点
        MatrixRequest = {
          "partStart": [0,  -4, 0],
          "partEnd": [0,  -distance-4, 0],
          "assemblyStart": [this.LineNode[index].x1, this.LineNode[index].y1, this.LineNode[index].z1],
          "assemblyEnd": [this.LineNode[index].x2, this.LineNode[index].y2, this.LineNode[index].z2]
        }
      }

      // 调用接口，计算转换矩阵
      let matrix= await this.transformMatrix(MatrixRequest);

      console.log(matrix);
      let mat = new Matrix4();
      mat.set(...matrix);

      // 导入紧固件
      await this.crownCADPlugin.command.assembly.insertComponent({
        docName: this.LineNode[index].text, position: new Point(0, 0, 0), matrix4: mat, boxCenter: 0
      }, 'featureName1' + index)
    },

    async generate2(index) {

      let pointRequest=  {
        "onePoint": [this.CircleNode[index].x1, this.CircleNode[index].y1, this.CircleNode[index].z1],
        "twoPoint": [this.CircleNode[index].x2, this.CircleNode[index].y2, this.CircleNode[index].z2],
      }

      // 计算紧固件上两点的距离
      let distance= await this.calculateDistance(pointRequest);

      if(this.CircleNode[index].text=== "NAS1473A3"){
        let pointRequest1=  {
          "onePoint": [this.LineNodes[index*2].x0, this.LineNodes[index*2].y0, this.LineNodes[index*2].z0],
          "twoPoint": [this.LineNodes[index*2+1].x0, this.LineNodes[index*2+1].y0, this.LineNodes[index*2+1].z0],
        }

        // 计算紧固件上两点的距离
        let distance1= await this.calculateDistance(pointRequest1);

        // 组装紧固件上起点、终点、真实坐标系下起点、终点
        let MatrixRequest= {
          "partStart": [0,  0, distance],
          "partEnd": [0,  0, 0],
          "partCenter": [0,  0.5*distance1, 0.5*distance],
          "assemblyStart": [this.CircleNode[index].x1, this.CircleNode[index].y1, this.CircleNode[index].z1],
          "assemblyEnd": [this.CircleNode[index].x2, this.CircleNode[index].y2, this.CircleNode[index].z2],
          "assemblyCenter": [this.LineNodes[index*2].x0, this.LineNodes[index*2].y0, this.LineNodes[index*2].z0]
        }

        // 调用接口，计算转换矩阵
        let matrix= await this.transformMatrixFromThreePoints(MatrixRequest);

        console.log(matrix);
        let mat = new Matrix4();
        mat.set(...matrix);
        // 导入紧固件
        await this.crownCADPlugin.command.assembly.insertComponent({
          docName: this.CircleNode[index].text, position: new Point(0, 0, 0), matrix4: mat, boxCenter: 0
        }, 'featureName2' + index)
      } else {
        let MatrixRequest1= {
          "partStart": [0, 5.3, 0],
          "partEnd": [0, 0, 0],
          "assemblyStart": [this.CircleNode[index].x1, this.CircleNode[index].y1, this.CircleNode[index].z1],
          "assemblyEnd": [this.CircleNode[index].x2, this.CircleNode[index].y2, this.CircleNode[index].z2]
        }
        // 调用接口，计算转换矩阵
        let matrix1= await this.transformMatrix(MatrixRequest1);

        let mat1 = new Matrix4();
        mat1.set( ...matrix1);


        await this.crownCADPlugin.command.assembly.insertComponent({
          docName: this.CircleNode[index].text, position: new Point(0, 0, 0), matrix4: mat1, boxCenter: 0
        }, 'featureName3'+ index)

      }
    },

    // 计算螺栓和螺母的矩阵信息，然后将对应的紧固件导入
    async generate3(index) {

      console.log(this.LineNodes[index].text);
      let MatrixRequest
      // 组装紧固件上起点、终点、真实坐标系下起点、终点，加一个厚度字典、方向
      if(this.LineNodes[index].text=== "MS20426AD3-4") {

        let cirlceIndex= Math.floor(index / 2)
        let A= [this.CircleNode[cirlceIndex].x1, this.CircleNode[cirlceIndex].y1, this.CircleNode[cirlceIndex].z1]
        let B= [this.CircleNode[cirlceIndex].x2, this.CircleNode[cirlceIndex].y2, this.CircleNode[cirlceIndex].z2]
        let C= [this.LineNodes[index].x0, this.LineNodes[index].y0, this.LineNodes[index].z0]
        let D= this.ointFromThirdAlongAB(A, B, C, 6.35)
        console.log('1111' + C)
        console.log('2222' + D)
        MatrixRequest= {
          "partStart": [2,0,0],
          "partEnd": [8.5,0,0],
          "assemblyStart": C,
          "assemblyEnd": D
        }
      }


      // 调用接口，计算转换矩阵
      let matrix= await this.transformMatrix(MatrixRequest);

      console.log(matrix);
      let mat = new Matrix4();
      mat.set(...matrix);

      // 导入紧固件
      await this.crownCADPlugin.command.assembly.insertComponent({
        docName: this.LineNodes[index].text, position: new Point(0, 0, 0), matrix4: mat, boxCenter: 0
      }, 'featureName4' + index)

    },
    ointFromThirdAlongAB(A, B, C, distance) {
      // 确保所有输入是数值（关键！）
      const a = A.map(Number);
      const b = B.map(Number);
      const c = C.map(Number);

      // 向量 AB
      const dx = b[0] - a[0];
      const dy = b[1] - a[1];
      const dz = b[2] - a[2];

      // 计算 AB 长度
      const lengthAB = Math.sqrt(dx * dx + dy * dy + dz * dz);
      if (lengthAB === 0) {
        throw new Error("点 A 和 B 不能重合，方向未定义。");
      }

      // 单位方向向量
      const ux = dx / lengthAB;
      const uy = dy / lengthAB;
      const uz = dz / lengthAB;

      // 计算新点 P：C + distance * 单位向量
      const Px = c[0] + ux * distance;
      const Py = c[1] + uy * distance;
      const Pz = c[2] + uz * distance;

      // 返回保留 4 位小数的数值数组（可按需调整）
      return [
        Number(Px.toFixed(6)),
        Number(Py.toFixed(6)),
        Number(Pz.toFixed(6))
      ];
    },
    // 上传xml文件接口
    async uploadFile(file) {
      try {
        const formData = new FormData();
        formData.append('file', file); // file 是从 <input type="file"> 获取的文件对象

        // const response = await axios.post("http://localhost:8080/" + 'uploadXml', formData, {
        //   headers: {
        //     'Content-Type': 'multipart/form-data',
        //   },
        // });
        let config = {
          timeout: 15000,
          headers: {
            'Content-Type': 'multipart/form-data',
          },
        };

        let url = 'fastener/uploadXml';
        let response = await request.post(url, formData, config);


        this.allNode= response.data;
        // 获取紧固件信息
        await this.getFastenerInfo();
      } catch (error) {
        console.error('文件上传失败:', error.response ? error.response.data : error.message);
      }
    },

    // 后台接口计算矩阵信息
    async transformMatrix(MatrixRequest) {
      try {
        let config = {
          timeout: 15000,
          headers: {
            'Content-Type': 'application/json'
          }
        };

        let url = 'fastener/transformMatrix';
        let response = await request.post(url, MatrixRequest, config);

        return response.data;
      } catch (error) {
        console.error('调用失败:', error.response ? error.response.data : error.message);
      }
    },

    // 后台接口计算矩阵信息(三个点）
    async transformMatrixFromThreePoints(MatrixRequest) {
      try {
        let config = {
          timeout: 15000,
          headers: {
            'Content-Type': 'application/json'
          }
        };

        let url = 'fastener/transformMatrixFromThreePoints';
        let response = await request.post(url, MatrixRequest, config);

        return response.data;
      } catch (error) {
        console.error('调用失败:', error.response ? error.response.data : error.message);
      }
    },

	  //弃用
    async calculateNewPoint(PointRequest) {
      try {
        let config = {
          timeout: 15000,
          headers: {
            'Content-Type': 'application/json'
          }
        };

        let url = 'fastener/calculateNewPoint';
        let response = await request.post(url, PointRequest, config);

        return response.data;
      } catch (error) {
        console.error('调用失败:', error.response ? error.response.data : error.message);
      }
    },

    // 计算紧固件上两点的距离
    async calculateDistance(PointRequest) {
      try {
        let config = {
          timeout: 15000,
          headers: {
            'Content-Type': 'application/json'
          }
        };

        let url = 'fastener/calculateDistance';
        let response = await request.post(url, PointRequest, config);

        return response.data;
      } catch (error) {
        console.error('调用失败:', error.response ? error.response.data : error.message);
      }
    },


  }
}
</script>

<style scoped>
>>> .el-form-item {
    margin-bottom: 5px!important;
}
>>> .el-form-item__label {
    margin-bottom: 5px!important;
}

>>> .el-form-item__content {
    display: flex;
    align-items: center;
}

>>> .el-form-item {
    height: 32px!important;
}
>>> .el-form-item__label {
    line-height: 32px !important;
    width: 80px!important;
}
>>> .el-upload-list__item {
    margin-top: 0px!important;
}
</style>
